import {importJWK, GeneralSign, generalVerify, CompactEncrypt, compactDecrypt, SignJWT, jwtVerify} from 'jose'

//https://jwt.io/
//https://github.com/panva/jose/blob/main/docs/classes/jws_general_sign.GeneralSign.md#readme

//现在登陆只用jws进行验证

export default {

  //根据本地私钥生成jwt
  async jwtSign(source, privateKey) {

    privateKey = "{\"p\":\"zmVGzCJLyCfwVI3-6bHRLFwaQFNRcAMlnY9g09BhkuMSngshKSrQgQg8pt4ACO3LXbgoCWBJK_QwpLdvgRGIqJSz3BZ2BccyzV89zweTG-tk387han-UI_aVCEekX_iUFS1UYmEgUGBazB_2dz1AWoTjm2ZY8d8KH69s7Hdf8LU\",\"kty\":\"RSA\",\"q\":\"t6SNnyoQKbQAUkLBIEz8-veCfc6KdS-_rkyQALFDry_C5ThCkzfDsc9pqgtwWmSwOo8VG9KXSk2Be8y8UdPV4F3-Bb7DxHAKYxV36YfhB5L5jqRw1A_4VxIDdgrn9np9LqXfwutRWbZe7s6VHVbEGR3KlpUBuixx-O1ysliTu58\",\"d\":\"AwZnxcikUSOIpEEjgrSVtV-kloaP3mvEdABFfTIiEPRE2Vw7A6aLRS7k_gmnqJqmQoaYist7GE-v5FUl8YS7q7uCvAIv5UySjXAub4fIqAm1D6Es6Ol3Xzn0OZ-kOOEIG5pTA6-dioDFcoSkZs7FL_mM1ww4kJKuxcwGN6wAE1bWswZc2g_tWpoDlRrLkx9IIcsljcTkYYJgoLkpfnaPQ3TdDWdFRUS87dp75TqZjNJuOqGjnNtIM4LxdwB9UeKEnZVOoaXUxFsJLogP_R4R80CFEmODCyhKbQJ3GWjJfP8LTEXORwH2C_tNc_o8pvJm6t_P-5Vzsj_Od9nZEjMGiQ\",\"e\":\"AQAB\",\"use\":\"sig\",\"kid\":\"123456\",\"qi\":\"x49We4vs-VHQB51Hx00RDc1zbuRX0gOUNyFVJsVxcA1TBoWTlAwl2UASDQmmBtaXqYeb9PSpymRNyuLX1xfps_tqoZYmenPmJww1R6eEI_bmJMfE1r__LTjO6D-WGsTBu05bvltNwAVCm7dZMViPqcFyaXk7OM2y2Q8mitO3VDk\",\"dp\":\"u3PcIxabAUTUz9bPSGyJb-KOrRF_C16wUTOhW38Mv52gkQ3Gpl8OU8KpY1yJZ5Khe5MAOdPLYTI847z-dpj4JzQ3TpLPyluq1j_EIT3d7COU0HhS3qjUYP1ZSdXXgpp_0-QBmgBgmt-IV5BIBvAIfK3pEoCYE8Tgqvpm0TVyW2k\",\"alg\":\"RS256\",\"dq\":\"nto2r0GBbbGIvZ-E014FT0oelJi-6BN_qVQNFKxBsh6MZh8-Z35LR1n1OuReMbL7RgxS5BhMSje1E9PL6rRlQ4nKnEmhqiCIu6DscxPYseaO_LZ96tJNrXOljsxsTqcx9dICNue7HPFGOSh1kEVnp5o_jfYi4lpj1EIBfwhj8l0\",\"n\":\"lA8Qq2IZMd8S4xa01WIohhbvZh9uHucfHomOtxXYcN1bggXOpqGJy0OF0XlYkb5ljdVg0Mf2BLzumw-J-T8gyDU9R301oB0IOR06Qc95XrUSzP-HkZDIfzO0-UhuOTatVk7jIfXpFIRKz0OqPis1GfOJk_2htIc8UNVeMoPe_VAb5zyXvClcEbvrSIF1njpqEL_80129gjE5VU363Qsb1tNQ1z0-r9H9bEgDPCBt6wvzfI4QdD4no5yEsCK1VV_HGnJy74HBdPRzGPyPTFut-ZVdOeKsbielJvlBT0a501YmD3KT9eG17nOlw3gCKeswY-tZD1IfRhWQzeDAqVm3aw\"}"
    console.log("1")
    const alg = JSON.parse(privateKey).alg
    console.log("2")
    const key = await importJWK(JSON.parse(privateKey), alg)
    console.log(key)

    const jwt = await new SignJWT({"payload": source})
      .setProtectedHeader({alg: alg})
      .setIssuedAt()
      .setIssuer('urn:example:issuer')
      .setAudience('urn:example:audience')
      .setExpirationTime('2h')
      .sign(key)

    console.log(jwt)
    console.log(typeof jwt)
  },
  //根据公钥验证jwt信息
  async jwtVerify(jwt, publicKey) {
    publicKey = "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"use\":\"sig\",\"kid\":\"123456\",\"alg\":\"RS256\",\"n\":\"lA8Qq2IZMd8S4xa01WIohhbvZh9uHucfHomOtxXYcN1bggXOpqGJy0OF0XlYkb5ljdVg0Mf2BLzumw-J-T8gyDU9R301oB0IOR06Qc95XrUSzP-HkZDIfzO0-UhuOTatVk7jIfXpFIRKz0OqPis1GfOJk_2htIc8UNVeMoPe_VAb5zyXvClcEbvrSIF1njpqEL_80129gjE5VU363Qsb1tNQ1z0-r9H9bEgDPCBt6wvzfI4QdD4no5yEsCK1VV_HGnJy74HBdPRzGPyPTFut-ZVdOeKsbielJvlBT0a501YmD3KT9eG17nOlw3gCKeswY-tZD1IfRhWQzeDAqVm3aw\"}"
    const alg = JSON.parse(publicKey).alg
    const key = await importJWK(JSON.parse(publicKey), alg)

    console.log(key)

    const {payload, protectedHeader} = await jwtVerify(jwt, key, {
      issuer: 'urn:example:issuer',
      audience: 'urn:example:audience'
    })

    console.log(protectedHeader)
    console.log(payload)
  },

  //encrypt with private key， JWS
  // key example:
  // {
  //     "kty": "EC",
  //     "d": "hM49J3m00g643PhcfnpmdI6z032WCaSVnr3L20632Vg",
  //     "use": "sig",
  //     "crv": "P-256",
  //     "kid": "123456",
  //     "x": "u-0tW7VZUHgUHoSljXkWHH7TNGb-WXkobDg33bjGzkU",
  //     "y": "yOQ1G1a9oLGUK7NgM9H2yKtinrU1mrKEM9K51f0ITFE",
  //     "alg": "ES256"
  // }
  async sign(source, key) {
    //key = "{\"kty\":\"EC\",\"d\":\"YAHn68qf8qKkkf8YjTjtJcgytyN6KwDWfBzoj91UxT0\",\"use\":\"sig\",\"crv\":\"P-256\",\"kid\":\"123456\",\"x\":\"56suvnA__jGWDwP8HRpjC_1qLvo8NE3cqiEXykeJvRU\",\"y\":\"q3dLAsOKHhJQDj9Aw0MxYW25fsBAFIA1RxkbLoBa75w\",\"alg\":\"ES256\"}"
    console.log("1")
    const alg = JSON.parse(key).alg
    console.log("2")
    console.log(JSON.parse(key))
    try{
      const ecPrivateKey = await importJWK(JSON.parse(key), alg)
      console.log(ecPrivateKey)
      const encoder = new TextEncoder()
      console.log("===before sign====")
      //新版本的sdk需要encoder.encode才可以
      const sign = new GeneralSign(encoder.encode(source))
      // const sign = new GeneralSign(source)
      console.log("===after sign====")
      console.log(sign)
      // sign.addSignature(ecPrivateKey)
      //     .setUnprotectedHeader({alg:'ES256',kid:JSON.parse(key).kid})
      sign.addSignature(ecPrivateKey)
        .setProtectedHeader({alg: alg, kid: JSON.parse(key).kid})
      const jws = await sign.sign()
      const signedResult = jws.signatures[0].protected + "." + jws.payload + "." + jws.signatures[0].signature
      console.log("signedResult: " + signedResult)
      return signedResult
    }catch (e){
      console.log(e)
    }
  },

  // decrypt with public key,注意这里的key一定是要public key，直接放private key也会报错
  // key example
  // {
  //     "kty": "EC",
  //     "use": "sig",
  //     "crv": "P-256",
  //     "kid": "123456",
  //     "x": "u-0tW7VZUHgUHoSljXkWHH7TNGb-WXkobDg33bjGzkU",
  //     "y": "yOQ1G1a9oLGUK7NgM9H2yKtinrU1mrKEM9K51f0ITFE",
  //     "alg": "ES256"
  // }
  async verify(jws, key) {
    const ecPublicKey = await importJWK(JSON.parse(key), 'ES256')
    const decoder = new TextDecoder()
    const {payload, protectedHeader} = await generalVerify(jws, ecPublicKey)
    console.log(payload + " " + protectedHeader)
    return decoder.decode(payload)
  },
  async encryptWithJWE(source, publicKey) {
    const encoder = new TextEncoder()
    const jwe = await new CompactEncrypt(encoder.encode(source))
      .setProtectedHeader({alg: 'ECDH-ES', enc: 'A256GCM'})
      .encrypt(publicKey)
    console.log(jwe)
    return jwe
  },
  async decryptWithJWE(jwe, privateKey) {
    const decoder = new TextDecoder()
    const {plaintext, protectedHeader} = await compactDecrypt(jwe, privateKey)
    console.log(protectedHeader)
    console.log(decoder.decode(plaintext))
  }
}


